<template>
  <div class="role">
    <page-search
      :search-config="searchConfig"
      @query-click="handleQueryClick"
      @reset-click="handleResetClick"
    ></page-search>
    <page-content
      ref="contentRef"
      :content-config="contentConfig"
      @new-data-click="handleNewClick"
      @edit-data-click="handleEditClick"
    />
    <page-modal
      ref="modalRef"
      :modal-config="modalConfig"
      :other-info="otherInfo"
    >
      <!--权限选择效果-->
      <template #menuList
        ><el-tree
          ref="treeRef"
          style="max-width: 600px"
          :data="entireMenus"
          show-checkbox
          node-key="id"
          :props="{ children: 'children', label: 'name' }"
          @check="handleElTreeCheck"
      /></template>
    </page-modal>
  </div>
</template>

<script lang="ts" setup>
import PageSearch from '@/components/page-search/page-search.vue'
import searchConfig from './config/search.config'
import PageContent from '@/components/page-content/page-content.vue'
import contentConfig from './config/content.config'
import pageModal from '@/components/page-modal/page-modal.vue'
import modalConfig from './config/modal.config'
import usePageModal from '@/hooks/usePageModal'
import usePageContent from '@/hooks/usePageContent'
import { storeToRefs } from 'pinia'
import useMainStore from '@/store/main/main'
import { ElTree } from 'element-plus'
import { ref, nextTick } from 'vue'
import { mapMenuListToIds } from '@/utils/map-menus'
//逻辑关系
const { modalRef, handleEditClick, handleNewClick } = usePageModal(
  newCallback,
  editCallBack
)

const { contentRef, handleQueryClick, handleResetClick } = usePageContent()
const treeRef = ref<InstanceType<typeof ElTree>>()
const mainStore = useMainStore()
//storeToRefs 是 Pinia 提供的一个工具函数，用于将 store 中的状态转换为响应式的 ref 对象。
//菜单数据可能会在应用运行过程中发生变化
const { entireMenus } = storeToRefs(mainStore)
//otherInfo: 包含所有选中的菜单id数组的对象
const otherInfo = ref({})
//data1: 当前选中的节点数据
//data2: 包含所有选中节点和半选节点信息的对象
function handleElTreeCheck(data1: any, data2: any) {
  //拿到所有选中的菜单id数组（el组件属性包含这些信息，可以打印查询）
  //data2.checkedKeys: 所有选中的节点ID ,这些节点及其所有子节点都被选中
  //data2.halfCheckedKeys: 半选中的节点ID,这些节点本身没有被选中，但其部分子节点被选中
  const menuList = [...data2.checkedKeys, ...data2.halfCheckedKeys]
  //将选中的菜单id数组和半选中的菜单id数组合并为一个数组
  otherInfo.value = { menuList }
}
//新建角色的时候清空勾选状态（新建时用到）
function newCallback() {
  nextTick(() => {
    treeRef.value!.setCheckedKeys([])
  })
}

//回显设置勾选状态（编辑时用到）
function editCallBack(itemData: any) {
  //编辑回调，拿到数据后，设置树形控件选中状态,将有权限的菜单数据传到nextTick中设置选中状态。
  // （注意：此处用的是nextTick，因为树形控件是异步渲染的）setCheckedKeys组件方法
  //数据是对象类型，在utils转换使用
  //nexttick:延迟到下次DOM更新循环之后执行读取操作。
  // 在Vue中，当你执行数据更新操作时（例如修改响应式对象中的属性），DOM并不会立即更新。
  // 这是因为Vue为了性能优化，会将多次的数据更改合并为一次实际的DOM更新。
  // 这就意味着如果你尝试在数据更新后立即读取或操作DOM，可能会得到旧的状态或者在修改一些数据后，
  // DOM还没有更新。nextTick提供了一个解决方案，它允许你在下一次DOM更新循环之后执行回调函数。
  // 如果要使用或依赖DOM的新状态，最好将这些操作放在nextTick中。
//预防 Tree 组件还没有完全渲染完成就开始设置勾选状态。
  nextTick(() => {
    const menuIds = mapMenuListToIds(itemData.menuList)

    treeRef.value!.setCheckedKeys(menuIds)
  })
}
</script>

<style lang="less" scoped></style>
